package huan.http;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.*;
import cn.hutool.json.JSONObject;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 作者:刘欢
 * @create 2024-03-04-11:30
 */
public class HttpUtilHuan {
   final String URL_GET = "www.baidu.com";
   final String URL_POST = "www.baidu.com";

    /**
     * GET请求栗子：
     * HttpUtil.get
     * 用于请求普通页面，然后返回页面内容的字符串
     */
    @Test
    public void HttpGet01(){
        //TODO 最简单的HTTP请求，可以自动通过header等信息判断编码，不区分HTTP和HTTPS
        String result1 = HttpUtil.get(URL_GET);
        System.out.println("result1 = " + result1);
    }
    @Test
    public void HttpGet02(){
        //TODO 当无法识别页面编码的时候，可以自定义请求页面的编码
        String result1 = HttpUtil.get(URL_GET, CharsetUtil.CHARSET_UTF_8);
        System.out.println("result1 = " + result1);
    }
    @Test
    public void HttpGet03(){
        //TODO 可以单独传入http参数，这样参数会自动做URL编码，拼接在URL中
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("city", "北京");
        String result1 = HttpUtil.get(URL_GET, paramMap);
        System.out.println("result1 = " + result1);
    }

    /**
     * TODO POST请求栗子：
     * HttpUtil.post
     * 用于请求普通页面，然后返回页面内容的字符串
     * 指定参数支持File对象，可实现文件上传，当然仅仅针对POST请求
     */
    @Test
    public void HttpPost01(){
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("city", "北京");
        String result= HttpUtil.post(URL_POST, paramMap);
        System.out.println(result);
    }

    /**
     * TODO 文件上传
     */
    @Test
    public void HttpPost02(){
        HashMap<String, Object> paramMap = new HashMap<>();
        //TODO 文件上传只需将参数中的键指定（默认file），值设为文件对象即可，对于使用者来说，文件上传与普通表单提交并无区别
        paramMap.put("file", FileUtil.file("D:\\HUAN\\face.jpg"));
        String result= HttpUtil.post(URL_POST, paramMap);
        System.out.println(result);
    }

    /**
     * TODO 文件下载
     */
    @Test
    public void HttpPost03(){
        String fileUrl = "https://cn.bing.com/images/search?view=detailV2&ccid=YeEKuzG%2b&id=3D807D2894E6D89A34A60FCD347B32308526E9A2&thid=OIP.YeEKuzG-cVORX2VQrQd1QgHaEo&mediaurl=https%3a%2f%2fts1.cn.mm.bing.net%2fth%2fid%2fR-C.61e10abb31be7153915f6550ad077542%3frik%3doukmhTAyezTNDw%26riu%3dhttp%253a%252f%252fi3.img.969g.com%252fdown%252fimgx2014%252f12%252f22%252f289_093449_8ced3.jpg%26ehk%3dmci1AffXHcwklYpn7cpFWSvZz3evIeDYflmll9wiy44%253d%26risl%3d%26pid%3dImgRaw%26r%3d0&exph=1050&expw=1680&q=%e5%9b%be%e7%89%87&simid=608018033788418931&FORM=IRPRST&ck=E8D27DAA53CC599508173D8867681156&selectedIndex=2&itb=0&ajaxhist=0&ajaxserp=0";
        //将文件下载后保存在d盘，返回结果为下载文件大小
        long size = HttpUtil.downloadFile(fileUrl, FileUtil.file("D:/tupian/"), new StreamProgress() {
        //TODO StreamProgress接口实现后可以感知下载过程中的各个阶段。
            @Override
            public void start() {
                Console.log("开始下载。。。。");
            }
            @Override
            public void progress(long progressSize) {
                Console.log("已下载：{}", FileUtil.readableFileSize(progressSize));
            }
            @Override
            public void finish() {
                Console.log("下载完成！");
            }
        });
        System.out.println("Download size: " + size);
    }

    /**
     * 本质上，HttpUtil中的get和post工具方法都是HttpRequest对象的封装，因此如果想更加灵活操作Http请求，可以使用HttpRequest。
     */
    @Test
    public void HttpRequest01(){
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("city", "北京");
        //TODO 链式构建请求
        String result2 = HttpRequest.post(URL_POST)
                .header(Header.USER_AGENT, "Hutool http")//头信息，多个头信息多次调用此方法即可
                .form(paramMap)//表单内容
                .timeout(20000)//超时，毫秒
                .execute().body();
        Console.log(result2);
    }

    /**
     * 指定请求头
     * 自定义Cookie（cookie方法）
     * 指定是否keepAlive（keepAlive方法）
     * 指定表单内容（form方法）
     * 指定请求内容，比如rest请求指定JSON请求体（body方法）
     * 超时设置（timeout方法）
     * 指定代理（setProxy方法）
     * 指定SSL协议（setSSLProtocol）
     * 简单验证（basicAuth方法）
     */
    @Test
    public void HttpRequest02(){
//        String json = "{'name':'lisi'}";
//        //TODO 链式构建请求  execute()执行请求  boby()获取响应内容
//        String result2 = HttpRequest.post(URL_POST)
//                        .body(json) //Restful 请求 指定请求内容，比如rest请求指定JSON请求体
//                        .execute().body();
//        Console.log(result2);

//        HttpResponse res = HttpRequest.post(URL_POST).execute();
//        Console.log(res.getStatus());

        HttpResponse res = HttpRequest.post(URL_POST).execute();
        //预定义的头信息
        Console.log(res.header(Header.CONTENT_ENCODING));
        //自定义头信息
        Console.log(res.header("Content-Disposition"));
    }


    /**
     *1.httpUtil使用post和get请求
     */
    @Test
    public void HuToolHttp1(){
        String url = "https://xxx/xx";//指定URL
        Map<String, Object> map = new HashMap<>();//存放参数
        map.put("A", 100);
        map.put("B", 200);
        HashMap<String, String> headers = new HashMap<>();//存放请求头，可以存放多个请求头
        headers.put("xxx", "xxx");
        //发送get请求并接收响应数据  createGet()打开get请求链接  addHeaders添加请求头  form存放参数    body获取响应
        String result1= HttpUtil.createGet(url).addHeaders(headers).form(map).execute().body();
        //发送post请求并接收响应数据 同上
        String result2= HttpUtil.createPost(url).addHeaders(headers).form(map).execute().body();
    }

    /**
     * 2.向指定URL发送DELETE请求，并携带请求头headers。
     */
    @Test
    public void HuToolHttp2(){
        int id = 0;
        String url = "https://xxx/delete/"+id;//指定URL携带ID
        HashMap<String, String> headers = new HashMap<>();//存放请求头，可以存放多个请求头
        headers.put("xxx", "xxx");
        //发送delete请求并接收响应数据
        String result= HttpUtil.createRequest(Method.DELETE, url).addHeaders(headers).execute().body();
    }

    /**
     *本质上，HttpUtil中的get和post工具方法都是HttpRequest对象的封装，因此如果想更加灵活操作Http请求，可以使用HttpRequest。
     */
    @Test
    public void HuToolHttp3() throws Exception{

        String url = "https://www.baidu.com";

        JSONObject json = new JSONObject();
        json.put("username", "1332788xxxxxx");
        json.put("password", "123456.");

        String result = HttpRequest.post(url)
                .header("Content-Type", "application/json")//TODO 头信息，多个头信息多次调用此方法即可
                .header("X-Bmob-Application-Id","2f0419a31f9casdfdsf431f6cd297fdd3e28fds4af")
                .header("X-Bmob-REST-API-Key","1e03efdas82178723afdsafsda4be0f305def6708cc6")
                .body(String.valueOf(json))
                .execute().body();
        System.out.println(result);
    }

    /**
     *  使用post方法请求
     */
    @Test
    public void HttpTest01(){
        Map<String,Object> paramap = new HashMap<>();
        paramap.put("app_id","123");
        paramap.put("app_key","456");
        paramap.put("ersers","798");

        //定义url路径
        String url = "";
        //调用createPost方法 建立链接   header设置请求头
        HttpRequest request = HttpUtil.createPost(url)
                .header("Content-Type…", "application/x-www-form-urlencoded;charset=utf-8");

        //循环请求参数  并放到请求中
        for (Map.Entry<String,Object> maps :paramap.entrySet() ){
            if (ObjectUtil.isNotEmpty(maps.getKey())){
                //循环获取请求内容
                request.form(maps.getKey(),maps.getValue());
            }
        }

        //String body = request.execute().body();  可以链式调用直接拿到响应

        //拆开
        //执行请求
        HttpResponse execute = request.execute();
        //拿到响应
        String body = execute.body();
        System.out.println(body);

    }

}
